/*
 * StartApplication.java
 *
 * Created on Jul 22, 2010 11:37:14 PM;
 */

package org.sunspotworld;

import com.sun.spot.core.resources.transducers.ISwitch;
import com.sun.spot.core.resources.transducers.ITriColorLED;
import com.sun.spot.core.resources.transducers.LEDColor;
import com.sun.spot.core.util.Utils;
import com.sun.spot.edemo.EDemoBoard;
import com.sun.spot.espot.service.BootloaderListenerService;
import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * The startApp method of this class is called by the VM to start the
 * application.
 * 
 * The manifest specifies this class as MIDlet-1, which means it will
 * be selected for execution.
 */
public class StartApplication extends MIDlet {

    private ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();
    private ISwitch [] sw = EDemoBoard.getInstance().getSwitches();

    private static final int INACTIVE = 0;
    private static final int CONNECTING = 1;
    private static final int COMPLETED = 2;
    private static final int IOERROR = 3;
    private static final int PROTOCOLERROR = 4;

    private static int POSTstatus = INACTIVE;

    private static String port = "51";

    private boolean running = true;

    private boolean pressed = false;

    private int sayingsCounter = 0;

    private int selection = 0;

    private String[] sayings = {
            "My awesome message 8",
            "My awesome message 9",
            "My awesome message 10",
            "My awesome message 11",
            "My awesome message 12",
            "My awesome message 13",
            "My awesome message 14",
        };

    /**
     * This method will monitor a radio connection with another remote spot.
     * The other spot will send over a integer which will be used to select the
     * message that is displayed on Twitter.
     * @throws MIDletStateChangeException
     */
    protected void startApp() throws MIDletStateChangeException {
        new BootloaderListenerService().start();   // monitor the USB (if connected) and recognize commands from host

        /** This is the base 64 encoding of the user name and password in the form
         * of username:password
         */
        String authString = "TkNTVVN1blNwb3RzOmNzYzQ1Mw==";

        RadiogramConnection rdgConnection = null;
        Radiogram rdg = null;

        try {
                rdgConnection = (RadiogramConnection) Connector.open("radiogram://:" + port);
                rdg = (Radiogram)rdgConnection.newDatagram(rdgConnection.getMaximumLength());
        } catch (IOException ex) {
                ex.printStackTrace();
        }

        while(running) {
            leds[7].setColor(LEDColor.GREEN);
            leds[7].setOn();

            try {
                rdg.reset();
                rdgConnection.receive(rdg);
                System.out.println("Got the message");
                selection = rdg.readInt();
            } catch(IOException e) {
                e.printStackTrace();
            }

            /**
             * This method call is where the program will check to see if the
             * selection variable is one decided by the other spot. Sending it
             * -1 will not send a post to twitter. Any number from 0 - 7 will
             * be accepted and send a post to twitter. 
             */
            checkSelection(selection, authString);
            System.out.println("Finished posting message");
            selection = -1;

            if(sw[0].isClosed() && sw[1].isClosed()) {
                running = false;
            }
        }


        notifyDestroyed();                      // cause the MIDlet to exit
    }

    /*
     * Posts a Twitter update. This method will establish a socket proxy connection
     * with the basestation which will send the post to twitter.
     * @param status text for the update
     * @param authStr authentication credentials to use for HTTP POST
     */
     public static void postTwitterUpdate(String status, String authStr) throws IOException {
        HttpConnection conn = null;
        OutputStream out = null;
        InputStream in = null;
        String resp = null;

        System.out.println("Posting: <" + status + ">");
        try {
            POSTstatus = CONNECTING;
            conn = (HttpConnection) Connector.open("http://twitter.com/statuses/update.xml");
            conn.setRequestMethod(HttpConnection.POST);
            conn.setRequestProperty("Connection", "close");
            conn.setRequestProperty("Authorization", "Basic " + authStr);

            out = conn.openOutputStream();
            out.write(("status='" + status + "'\n").getBytes());
            out.flush();

            in = conn.openInputStream();
            resp = conn.getResponseMessage();
            if (resp.equals("OK")) {
                POSTstatus = COMPLETED;
            } else {
                POSTstatus = PROTOCOLERROR;
            }
        } catch (IOException ex) {
            POSTstatus = IOERROR;
            ex.printStackTrace();
        } finally {
            if (in != null) in.close();
            if (out != null) out.close();
            if (conn != null) conn.close();
        }

        if (POSTstatus != COMPLETED)
            System.out.println("Posting failed: " + resp);
        System.out.println("Posting Completed");
    }

     /**
      * This method will check the integer sent by the radiograms to see if it
      * is a number that is in the array of sayings. If the number is -1, the
      * method will immediately return. If the number is from 0-7, then it will
      * pick that index out of the array of sayings and call the postTwitterUpdate
      * method.
      * @param index
      * @param authString
      */
    public void checkSelection(int index, String authString) {
        if(index != -1) {
                leds[7].setOff();
                for(int i = 0; i < leds.length; i++) {
                    leds[i].setColor(LEDColor.GREEN);
                    leds[i].setOn();
                    Utils.sleep(200);
                }
                try {
                    postTwitterUpdate(sayings[index] + " @ " + System.currentTimeMillis(), authString);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                for(int i = 0; i < leds.length; i ++) {
                    Utils.sleep(200);
                    leds[i].setOff();
                }
            }
    }

    protected void pauseApp() {
        // This is not currently called by the Squawk VM
    }

    /**
     * Called if the MIDlet is terminated by the system.
     * I.e. if startApp throws any exception other than MIDletStateChangeException,
     * if the isolate running the MIDlet is killed with Isolate.exit(), or
     * if VM.stopVM() is called.
     * 
     * It is not called if MIDlet.notifyDestroyed() was called.
     *
     * @param unconditional If true when this method is called, the MIDlet must
     *    cleanup and release all resources. If false the MIDlet may throw
     *    MIDletStateChangeException  to indicate it does not want to be destroyed
     *    at this time.
     */
    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
        for (int i = 0; i < 8; i++) {
            leds[i].setOff();
        }
    }
}
